package com.cdck.safe.dete.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cdck.safe.dete.mapper.ResourceRecordMapper;
import com.cdck.safe.dete.mapper.SysDictMapper;
import com.cdck.safe.dete.model.bo.ResourceBO;
import com.cdck.safe.dete.model.entity.*;
import com.cdck.safe.dete.mapper.ResourceMapper;
import com.cdck.safe.dete.model.query.BaseKeywordsQuery;
import com.cdck.safe.dete.model.vo.*;
import com.cdck.safe.dete.service.ResourceRecordService;
import com.cdck.safe.dete.service.ResourceService;
import com.cdck.safe.dete.service.SysUserService;
import lombok.RequiredArgsConstructor;
import org.redisson.api.mapreduce.RMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (Resource)表服务实现类
 *
 * @author wp
 * @since 2024-05-18 14:33:03
 */
@Service
@RequiredArgsConstructor
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements ResourceService {

    private final SysDictMapper sysDictMapper;
    private final ResourceRecordMapper resourceRecordMapper;
    private final ResourceRecordService resourceRecordService;
    private final SysUserService sysUserService;
//    private final ResourceService resourceService;
    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public Resource getResourceFormData(Long id) {
        return this.getById(id);
    }

    /**
     * 分页查询
     * <p>
     * queryParams 筛选条件
     *
     * @return 查询结果
     */
    @Override
    public IPage<ResourceVO> queryByPage(BaseKeywordsQuery queryParams) {
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        String keywords = queryParams.getKeywords();
        Page<Resource> page = new Page<>(pageNum, pageSize);
        Page<ResourceVO> pageVO = new Page<>(pageNum, pageSize);

        Page<Resource> resourcePage = this.page(
                page,
                new LambdaQueryWrapper<Resource>()
                        .like(
                                StrUtil.isNotBlank(keywords), Resource::getName, keywords
                        )
                        .orderByAsc(Resource::getUpdateTime)
        );

        List<ResourceVO> voList = resourcePage.getRecords().stream().map(item -> {
            ResourceVO resourceVO = new ResourceVO();
            BeanUtils.copyProperties(item, resourceVO);
            LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysDict::getTypeCode, "resourceType");
            queryWrapper.eq(SysDict::getValue, item.getType());
            SysDict sysDict = sysDictMapper.selectOne(queryWrapper);
            if (sysDict != null) {
                resourceVO.setType(sysDict.getName());
            }
            return resourceVO;
        }).collect(Collectors.toList());
        BeanUtils.copyProperties(page, pageVO, "records");
        pageVO.setRecords(voList);
        return pageVO;
    }

    /**
     * 新增数据
     *
     * @param resource 实例对象
     * @return 实例对象
     */
    @Override
    public boolean saveResource(Resource resource) {
        resource.setCreateTime(new Date());
        resource.setUpdateTime(new Date());
        return this.save(resource);
    }

    /**
     * 修改数据
     *
     * @param resource 实例对象
     * @return 实例对象
     */
    @Override
    public boolean updateResource(Long id, Resource resource) {
        return this.updateById(resource);
    }

    /**
     * 通过主键删除数据
     *
     * @param idsStr ids集合
     * @return 是否成功
     */
    @Override
    public boolean deleteResources(String idsStr) {
        Assert.isTrue(StrUtil.isNotBlank(idsStr), "删除的数据为空");
        // 逻辑删除
        List<Long> ids = Arrays.stream(idsStr.split(","))
                .map(Long::parseLong).collect(Collectors.toList());
        return this.removeByIds(ids);
    }

    @Override
    public boolean applicationData() {

        return false;
    }

    @Override
    public List<ResourceStatusVO> getResourceStatus(ResourceBO resourceBO) {

        LambdaQueryWrapper<Resource> seatQueryWrapper = new LambdaQueryWrapper<>();

        List<Resource> resourceList = this.list(seatQueryWrapper);
        if (resourceList != null && resourceList.size() > 0) {
            List<ResourceStatusVO> voList = resourceList.stream().map(item -> {
                ResourceStatusVO vo = new ResourceStatusVO();
                Resource resource = this.getById(item.getId());
                vo.setResourceName(resource.getName());
                BeanUtils.copyProperties(item, vo);
                //查找这个作座位的所有预约记录
                LambdaQueryWrapper<ResourceRecord> bookingWrapper = new LambdaQueryWrapper<>();
                bookingWrapper
                        .eq(ResourceRecord::getResourceId, item.getId())
                        .eq(ResourceRecord::getStatus, 2)
                        .gt(ResourceRecord::getEndTime, LocalDateTime.now());
                List<ResourceRecord> recordList = resourceRecordMapper.selectList(bookingWrapper);
                if (recordList == null && recordList.size() == 0) {
                    //没有预约记录，直接返回
                    return vo;
                }
                for (ResourceRecord record : recordList) {
                    //如果这个时间段，记录表里面有记录，且在使用范围，说明作为被占用
                    long bookingStartTime = record.getStartTime().getTime();
                    long bookingEndTime = record.getEndTime().getTime();
                    long seatStartTime = resourceBO.getStartTime().getTime();
                    long seatEndTime = resourceBO.getEndTime().getTime();

                    // 检查预订与座位时间范围是否有交叉,三种情况
                    if ((seatStartTime >= bookingStartTime && seatEndTime <= bookingEndTime)
                            || (seatStartTime <= bookingStartTime && seatEndTime >= bookingStartTime)
                            || (seatStartTime <= bookingEndTime && seatEndTime >= bookingEndTime)) {
                        vo.setStatus(1); // 设置座位状态为已预订
                    }
                }
                return vo;
            }).collect(Collectors.toList());

            return voList;
        }

        return new ArrayList<>();
    }

    @Override
    public IPage<ResourceRecordVO> getApplicationPage(BaseKeywordsQuery queryParams) {
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        Page<ResourceRecord> page = new Page<>(pageNum, pageSize);
        Page<ResourceRecordVO> pageVO = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<ResourceRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ResourceRecord::getStatus,0);
        Page<ResourceRecord> resourcePage = resourceRecordService.page(
                page,
                queryWrapper
        );

        List<ResourceRecordVO> recordVOList = resourcePage.getRecords().stream().map(item -> {
            ResourceRecordVO vo = new ResourceRecordVO();
            BeanUtils.copyProperties(item, vo);
            vo.setStatusDesc(getStatusDesc(item.getStatus()));
            SysUser sysUser = sysUserService.getById(item.getUserId());
            if (sysUser != null) {
                vo.setUserName(sysUser.getNickname());
            }
            Long resourceId = item.getResourceId();
            com.cdck.safe.dete.model.entity.Resource resource = this.getById(resourceId);
            if (resource != null) {
                vo.setResourceName(resource.getName());
            }

            SysUser applicationUser = sysUserService.getById(item.getApplicationId());
            if (applicationUser != null) {
                vo.setApplicationName(applicationUser.getNickname());
            }
            return vo;
        }).collect(Collectors.toList());
        BeanUtils.copyProperties(resourcePage, pageVO, "records");
        pageVO.setRecords(recordVOList);
        return pageVO;
    }
    public String getStatusDesc(Integer status) {
        switch (status) {
            case 0:
                return "待审核";
            case 1:
                return "驳回";
            case 2:
                return "通过";
            case 3:
                return "完成";
            case 4:
                return "取消";
        }
        return "未知";
    }
}
